package lesson04.作业.作业02;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 面试题： 写一个固定容量同步容器，拥有put和get方法，以及getCount方法
 * 能够支持2个生产者线程以及10个消费者线程的阻塞调用
 */
public class ThreadDome01 {

    private volatile List lists = new ArrayList<>();
    // private final static Integer MaxLenght = 10;
    public void put(Object a){
        lists.add(a);
    }

    public Object get(){
        return lists.remove(0);
    }
    public Integer getCount(){
        return lists.size();
    }

    public static void main(String[] args) throws Exception {

        Thread[] serve = new Thread[5];
        Thread[] clent = new Thread[10];
        ThreadDome01 list = new ThreadDome01();
        final Object lock = new Object();
        Integer maxCount = 10;
        // 生产者

        for (int i = 0; i < serve.length; i++) {
            serve[i] = new Thread(() -> {
                System.out.println("启动生产者.... "+ Thread.currentThread().getName());
                while (true) {
                    synchronized (lock) {
                        // 路过生产到最大数量，暂停线程
                        if (list.getCount() == maxCount) {
                            lock.notify();
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            } finally {
                                // lock.notify();
                            }
                        }else  {
                            //System.out.println("server ... size == 0");
                            list.put(new Object());
                            System.out.println(Thread.currentThread().getName()+" add  count: " + list.getCount());
                            // lock.notify();
                        }

                    }
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "serve-"+i);

        }

        // 消费者

        for (int i = 0; i < clent.length; i++) {
            clent[i] = new Thread(() -> {
                System.out.println("启动消费者--"+ Thread.currentThread().getName());
                while (true){
                    synchronized (lock) {
                        if(list.getCount()>0){
                            list.get();
                            System.out.println("         "+Thread.currentThread().getName() + " remove  count: " + list.getCount());
                            // lock.notify();
                        }else{
                            lock.notify();
                            try {
                                lock.wait();
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                    try {
                        TimeUnit.SECONDS.sleep(1);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }, "client-》"+i);
        }

        for (int i = 0; i < serve.length; i++) serve[i].start();
        // TimeUnit.SECONDS.sleep(2);
        for (int i = 0; i < clent.length; i++) clent[i].start();

    }
}
